package org.common.utils.rpc.generator.entity;

import javassist.*;

import java.io.IOException;

/**
 * 基于javassist的类构建器
 * @author zhouzhibing
 * @date 2025/11/15 20:08
 */
public class ClassBuilder {

    /**
     * 类对象
     */
    private CtClass ctClass;
    /**
     * 类池
     */
    private static final ClassPool CLASS_POOL = ClassPool.getDefault();

    public ClassBuilder(String className) {
        this.ctClass = CLASS_POOL.makeClass(className);
    }

    /**
     * 导入包
     * @param packageName 包名
     * @return ClassBuilder
     */
    public ClassBuilder addImportPackage(String packageName) {
        CLASS_POOL.importPackage(packageName);
        return this;
    }

    /**
     * 添加接口
     * @param interfaceName 接口名称
     * @return ClassBuilder
     * @throws Exception 创建异常
     */

    public ClassBuilder addInterface(String interfaceName) throws Exception {
        CtClass interfaceClass = CLASS_POOL.get(interfaceName);
        ctClass.setInterfaces(new CtClass[]{interfaceClass});
        return this;
    }

    /**
     * 添加字段
     * @param fieldSource 字段源代码
     * @return ClassBuilder
     * @throws Exception 创建异常
     */
    public ClassBuilder addField(String fieldSource) throws Exception {
        ctClass.addField(CtField.make(fieldSource, ctClass));
        return this;
    }

    /**
     * 添加方法
     * @param methodSource 方法源代码
     * @return ClassBuilder
     * @throws Exception 创建异常
     */
    public ClassBuilder addMethod(String methodSource) throws Exception {
        ctClass.addMethod(CtNewMethod.make(methodSource, ctClass));
        return this;
    }

    public ClassBuilder addMethod(CtClass returnType , String name , CtClass[] parameterTypes , CtClass[] exceptions , String body) {
        try {
            CtMethod ctMethod = CtNewMethod.make(returnType , name , parameterTypes , exceptions , body , ctClass);
            ctClass.addMethod(ctMethod);
        } catch (CannotCompileException e) {
            throw new RuntimeException(e);
        }
        return this;
    }

    /**
     * 添加构造方法
     * @param constructorSource 构造方法源代码
     * @return ClassBuilder
     * @throws Exception 创建异常
     */
    public ClassBuilder addConstructor(String constructorSource) throws Exception {
        ctClass.addConstructor(CtNewConstructor.make(constructorSource, ctClass));
        return this;
    }

    /**
     * 构建类
     * @return 类对象
     * @throws Exception 创建异常
     */
    public Class<?> build() throws Exception {
        ctClass.detach();
        return ctClass.toClass();
    }

    /**
     * 把当前class写入文件
     */
    public void writeFile() {
        try {
//            ctClass.writeFile("./javassist-classes/");
            ctClass.debugWriteFile("./javassist-classes/");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static ClassPool getClassPool() {
        return CLASS_POOL;
    }
}
